# -*- coding:utf-8 -*-
"""
    后门检测部分
"""
@config(alias="ld_preload", enable=True)
def check_LD_PRELOAD(option):
    """LD_PRELOAD后门检测"""
    suspicious = False
    if 1:
        suspicious= check_tag('LD_PRELOAD后门', 'LD_PRELOAD')
        return suspicious
    else:
        return suspicious

@config(alias="ld_aout_preload", enable=False)
def check_LD_AOUT_PRELOAD(option):
    """LD_AOUT_PRELOAD后门检测"""
    suspicious= False
    if 1:
        suspicious = check_tag('LD_AOUT_PRELOAD后门', 'LD_AOUT_PRELOAD')
        return suspicious
    else:
        return suspicious

@config(alias="ld_elf_preload", enable=False)
def check_LD_ELF_PRELOAD(option):
    """LD_ELF_PRELOAD后门检测"""
    suspicious = False
    if 1:
        suspicious = check_tag('LD_ELF_PRELOAD后门', 'LD_ELF_PRELOAD')
        return suspicious
    else:
        return suspicious

@config(alias="ld_library_path", enable=True)
def check_LD_LIBRARY_PATH(option):
    """LD_LIBRARY_PATH后门检测"""
    suspicious = False
    if 1:
        suspicious = check_tag('LD_LIBRARY_PATH后门', 'LD_LIBRARY_PATH')
        return suspicious
    else:
        return suspicious

@config(alias="prompt_command", enable=True)
def check_PROMPT_COMMAND(option):
    """PROMPT_COMMAND后门检测"""
    suspicious = False
    if 1:
        suspicious= check_tag('PROMPT_COMMAND后门', 'PROMPT_COMMAND')
        return suspicious
    else:
        return suspicious

@config(alias="export", enable=True)
def check_export(option):
    """未知环境变量后门"""
    suspicious= False
    if 1:
        suspicious = check_tag('未知环境变量后门', 'PATH', mode='all')
        return suspicious
    else:
        return suspicious

@config(alias="ld_so_preload", enable=True)
def check_ld_so_preload(option):
    """/etc/ld.so.preload 后门检测"""
    malice = False
    if 1:
        if not os.path.exists('/etc/ld.so.preload'): 
            monitoring_objects_num("ld_so_preload") # 文件不存在，检测项加1
            return malice
        danger_file("/etc/ld.so.preload")
        with open('/etc/ld.so.preload') as f:
            for line in f:
                monitoring_objects_num("ld_so_preload") # 对每一行内容都要检测，所以检测项都加1
                if not len(line) > 3: 
                    continue
                if line[0] != '#':
                    log("监测到preload劫持行为 /etc/ld.so.preload -> {}".format(red(line.strip())))
                    save_result("preload后门劫持", "设置了 /etc/ld.so.preload", 'h')
                    content = analysis_strings(line)
                    if content:
                        save_result("preload后门劫持", "/etc/ld.so.preload 存在：%s" % tag, 'h')
                        malice = True
        return malice
    else:
        return malice

@config(alias="cron", enable=True)
def check_cron(option):
    """分析cron定时任务后门"""
    malice = False
    if 1:
        cron_dir_list = ['/var/spool/cron/', '/etc/cron.d/', '/etc/cron.daily/', '/etc/cron.weekly/',
                         '/etc/cron.hourly/', '/etc/cron.monthly/']
        for cron in cron_dir_list:
            for file in gci(cron):
                monitoring_objects_num("cron") # 文件存在与否都要进行判断，所以加上检查项。
                if not os.path.exists(file): continue
                if os.path.isdir(file): continue
                try:
                    for i in open(file, 'r'):
                        content = analysis_strings(i)
                        if content:
                            # save_result("cron定时任务后门检测", str(content), "m")
                            save_result("cron后门检测", "请检查该文件：%s"%(file), "m")

                            malice = True
                except Exception as e:
                    log("文件权限问题")
        return malice
    else:
        return malice

@config(alias="ssh", enable=True)
def check_SSH(option):
    """分析SSH后门"""

    """
    netstat -ntpl |grep -v ':22 ' | awk '{if (NR>2){print $7}}'

    """
    malice = False
    if 1:
        infos = os.popen(
            "netstat -ntpl 2>/dev/null |grep -v ':22 '| awk '{if (NR>2){print $7}}' | sort -r | uniq").read().splitlines()
        if not len(infos):
            monitoring_objects_num("ssh") # 没有ssh检测信息，统计项加1
            return malice
        
        for info in infos:
            pid = info.split("/")[0]
            monitoring_objects_num("ssh") # 每条ssh信息，都要进行检测，所以每条检测信息都要加1
            if os.path.exists('/proc/%s/exe' % pid):
                if 'sshd' in os.readlink('/proc/%s/exe' % pid):
                    save_result("SSH后门检测", "SSH后门非22端口的sshd进程pid：%s"%(pid), "h")
                    malice = True              
        return malice
    else:
        return malice

@config(alias="sshwrapper", enable=True)
def check_SSHwrapper(option):
    """分析SSH Server wrapper 后门"""
    malice = False
    if 1:
        infos = os.popen("file /usr/sbin/sshd 2>/dev/null").read().splitlines()
        if not len(infos):
            monitoring_objects_num("sshwrapper") # 没有信息，统计监测项加1
            return malice
        # if ('ELF' not in infos[0]) and ('executable' not in infos[0]):
        monitoring_objects_num("sshwrapper") # 存在信息，统计监测项加1
        if ('ELF' not in infos[0]): # 暂时过滤掉executable的判断
            save_result("SSH wrapper后门检测", "/usr/sbin/sshd被篡改,文件非ELF可执行文件 rm /usr/sbin/sshd & yum -y install openssh-server & service sshd start #删除sshd异常文件，并重新安装ssh服务", "m")
            malice = True
        return malice
    else:
        return  malice

# @config(alias="inetd", enable=False)
# def check_inetd(option):
#     """分析inetd后门"""

#     malice = False
#     # if 1:
#     if 1:
#         if not os.path.exists('/etc/inetd.conf'): return malice
#         with open('/etc/inetd.conf') as f:
#             for line in f:
#                 content = analysis_strings(line)
#                 if content:
#                     save_result("inetd后门检测", "请查看/etc/inetd.conf配置文件，存在异常%s"%(content), "m")
#                     malice = True
#         return malice
#     # else:
#     #     return malice

# @config(alias="xinetd", enable=True)
# def check_xinetd(option):
#     """分析xinetd后门"""
#     malice = False

#     # if 1:
#     if 1:
#         if not os.path.exists('/etc/xinetd.conf'):
#             return
#         with open('/etc/xinetd.conf')as f:
#             for line in f:
#                 content = analysis_strings(line)
#                 if content:
#                     save_result("xinetd后门检测", "请查看/etc/xinetd.conf配置文件，存在异常", "h")
#                     malice = True
#         if not os.path.exists('/etc/xinetd.d/'):
#             print(3333)
#             return suspicious, malice
#         for file in os.listdir('/etc/xinetd.d/'):
#             print(1111, file)
#             with open(os.path.join('%s%s' % ('/etc/xinetd.d/', file))) as f:
#                 for line in f:
#                     print("check_xinetd", line)
#                     content = analysis_strings(line)
#                     if content:
#                         save_result(u'常规后门检测', u'xinetd.conf 后门', u'/etc/xinetd.conf', '', content,
#                                       u'[1]cat /etc/xinetd.conf', u'风险', programme=u'vi /etc/xinetd.conf #删除异常点')
#                         malice = True
#         return malice
#     # else:
#     #     return  malice

@config(alias="setuid", enable=True)
def check_setuid(option):
    """分析setuid后门"""
    suspicious = False
    if 1:
        file_infos = os.popen(
            "find / ! -path '/proc/*' ! -path '/sys/*' ! -path '/dev/*' ! -path '/var/lib/docker/*' -type f -perm -4000 2>/dev/null | grep -vEw 'pam_timestamp_check|unix_chkpwd|ping|ping6|fusermount|mount|umount|su|sudo|pt_chown|ssh-keysign|at|passwd|gpasswd|chsh|crontab|chfn|usernetctl|staprun|newgrp|chage|dhcp|userhelper|helper|pkexec|top|Xorg|nvidia-modprobe|quota|login|security_authtrampoline|authopen|traceroute6|traceroute|ps'").read().splitlines()
        if not len(file_infos):
            monitoring_objects_num("setuid") # 没有信息，统计监测项加1
            return suspicious
        for info in file_infos:
            monitoring_objects_num("setuid") # 检测每一项，都得加1
            danger_file(info)
            save_result("setuid后门检测", "文件：%s被设置setuid属性，通常此类被设置权限的文件执行后会给予普通用户root权限"%(info), "m")
            suspicious = True
        return suspicious
    else:
        return suspicious

@config(alias="startup", enable=True)
def check_startup(option):
    """系统启动项检测"""
    malice = False
    if 1:
        init_path = ['/etc/init.d/', '/etc/rc.d/', '/etc/rc.local', '/usr/local/etc/rc.d',
                     '/usr/local/etc/rc.local', '/etc/conf.d/local.start', '/etc/inittab', '/etc/systemd/system/']
        for path in init_path:
            if not os.path.exists(path):
                monitoring_objects_num("startup") # 文件不存在，检测项加1
                continue
            if os.path.isfile(path):
                monitoring_objects_num("startup") #  文件存在，检测项加1
                content = analysis_file(path) # 读取文件内容（前20M或前200行），然后进行shell_check(shell反弹检测)，保存数据到g_dangerous_files = {}中，返回True
                if content:
                    save_result("系统启动项检测后门检测", "请检查该文件：%s "% (path), "h")
                    malice = True
                continue
            for file in gci(path): # gci 获取目录下的文件路径
                monitoring_objects_num("startup") #  文件存在，检测项加1
                content = analysis_file(file)
                if content:
                    save_result("系统启动项检测后门检测", "请检查该文件：%s"% (file), "h")
                    malice = True
        return malice
    else:
        return malice
